package com.kstech.ks_gaz01.base

import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.text.method.ScrollingMovementMethod
import android.view.KeyEvent
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.view.isVisible
import androidx.navigation.Navigation.findNavController
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import com.blankii.androidlibrary.base.BaseBindingActivity
import com.blankii.androidlibrary.exts.logd
import com.blankii.androidlibrary.exts.logw
import com.blankii.androidlibrary.exts.startActivity
import com.blankii.androidlibrary.init.Config
import com.blankii.androidlibrary.init.LibraryMainActivity
import com.blankii.androidlibrary.lib.permission.PermissionManager
import com.blankii.androidlibrary.lib.permission.PermissionResultListener
import com.blankii.androidlibrary.utils.CalcUtil
import com.blankii.androidlibrary.utils.HardwareInfoUtil.getAndroidId
import com.blankii.androidlibrary.utils.RWUtil
import com.blankii.androidlibrary.utils.RWUtil.getTime
import com.blankii.androidlibrary.utils.RWUtil.readFileByLines
import com.blankii.androidlibrary.utils.RWUtil.writeFileByLines
import com.blankii.androidlibrary.utils.ViewClickContinuousUtil
import com.kstech.ks_gaz01.R
import com.kstech.ks_gaz01.XML_ADDRESS_SAVE_PARAM
import com.kstech.ks_gaz01.XML_DEVICE_NAME_GCH10
import com.kstech.ks_gaz01.XML_VALUE_SAVE_PARAM
import com.kstech.ks_gaz01.XML_XS_BD
import com.kstech.ks_gaz01.currentCarName
import com.kstech.ks_gaz01.data.DebugDataBean
import com.kstech.ks_gaz01.databinding.ActivityHomeBinding
import com.kstech.ks_gaz01.databinding.LayoutDialogMoreBinding
import com.kstech.ks_gaz01.databinding.LayoutIsvalidBinding
import com.kstech.ks_gaz01.databinding.LayoutUseTimeoutBinding
import com.kstech.ks_gaz01.fragments.CarChooseManagerFragment
import com.kstech.ks_gaz01.socket.SocketConnectedStatus
import com.kstech.ks_gaz01.socket.SocketConnectionStatusListener
import com.kstech.ks_gaz01.socket.SocketManagerNew
import java.io.File

/**
 * author: blankii
 * created on: 2024/4/30 10:13
 * description: 优化目标：如何优雅的在activity 监听navigation 切换状态
 *
 * bug：发现第一个启动页fragment生命周期异常:onCreate-onStart-onResume-onPause-onResume onPause为甚么会调用？？
 * 答：在activity中错误使用navigation.addOnDestinationChangedListener
 *
 * 侯林模拟器分辨率 1920x1130 dpi:240
 *
 */
class HomeActivity : BaseBindingActivity<ActivityHomeBinding>(ActivityHomeBinding::inflate, false),
    SocketConnectionStatusListener {
    private lateinit var errorMsg: String
    private lateinit var appFile: File
    private var isHomeFragment: Boolean = false
    private val REQUEST_MANAGER_PERMISSION = 999
    private val mViewModel: HomeViewModel by viewModels()

    override fun onInitView() {
        if (Config.debugAndroidLibrary) {
            this@HomeActivity.startActivity<LibraryMainActivity>()
        }
        checkLogin()
        mViewModel.testStr = "HomeActivity"

    }

    private fun checkLogin() {
        /**
         * 判断是否授权
         */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // 先判断有没有权限
            if (Environment.isExternalStorageManager()) {
                doWorkWithPermission()
            } else {
                val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
                intent.setData(Uri.parse("package:" + this.packageName))
                ActivityCompat.startActivityForResult(
                    this, intent, REQUEST_MANAGER_PERMISSION, null
                )
            }
        } else {
            PermissionManager.requestPermissions(
                this, object : PermissionResultListener {
                    override fun success() {
                        doWorkWithPermission()
                    }

                    override fun failure() {
                        /**
                         * 没有授权
                         */
                        val isValidBinding = LayoutIsvalidBinding.inflate(layoutInflater)
                        setContentView(isValidBinding.root)
                        isValidBinding.isValid.text =
                            "应用平板读写权限未授权，请在设置-应用-找到本应用打开"
                    }
                }, *arrayOf(
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                )
            )
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        requestCode.toString().logd("requestCode")
        requestCode.toString().logd("resultCode")
        if (requestCode == REQUEST_MANAGER_PERMISSION) {
            doWorkWithPermission()
        }
    }

    private fun doWorkWithPermission() {
        appFile = RWUtil.getAppFile()
        /**
         * md5 是否匹配
         */
        if (isValid()) {//isValid()
            /**
             * 软件是否使用超时
             */
            if (isUseTimeOut()) {//isUseTimeOut()
                /**
                 * 超时
                 */
                val useTimeOutBinding = LayoutUseTimeoutBinding.inflate(
                    layoutInflater
                )
                setContentView(useTimeOutBinding.root)
                useTimeOutBinding.useTimeOutMsg.text = errorMsg
                useTimeOutBinding.authInfo.setText(RWUtil.getClipData(this@HomeActivity))
                useTimeOutBinding.submit.setOnClickListener {
                    val editText = useTimeOutBinding.authInfo.text.toString()
                    if (editText.isNullOrEmpty()) {
                        useTimeOutBinding.useTimeOutMsg.text = "请输入值"
                        return@setOnClickListener
                    }
                    var inputInfo = ""
                    try {
                        inputInfo = RWUtil.deAESByKey(
                            RWUtil.getAndroidIdLastStr(), editText
                        )
                    } catch (e: Exception) {
                        useTimeOutBinding.useTimeOutMsg.text =
                            "输入使用时间码无法解析，请联系杭州爱知工作人员"
                        return@setOnClickListener
                    }
                    if (inputInfo.length != RWUtil.getValidTimeLength()) {
                        useTimeOutBinding.useTimeOutMsg.text =
                            "解析数据为:$inputInfo,数据格式不符合，请联系杭州爱知工作人员"
                    } else {
                        writeFileByLines(
                            appFile, RWUtil.AppTxtBean(
                                getAndroidId(), inputInfo, getTime()
                            )
                        )
                        useTimeOutBinding.useTimeOutMsg.text =
                            "输入使用时间码格式正确，请退出重新登入\r\n 您当前最大使用时长为:$inputInfo"
                    }
                }
            } else {
                /**
                 * 正常使用
                 */
                setContentView(binding.root)

                /**
                 * 与socket 绑定
                 */
                SocketManagerNew.subscribeSocketConnectionListener(this@HomeActivity)
                initView()
            }
        } else {
            /**
             * 没有授权
             */
            val isValidBinding = LayoutIsvalidBinding.inflate(
                layoutInflater
            )
            setContentView(isValidBinding.root)
            isValidBinding.isValid.text = errorMsg
        }
    }

    override fun onInitData() {

    }

    /**
     * 判定使用时长是否超时
     * 每次读的时候读一次是否使用时长大于使用上限
     * 每次写的时候，先读一次再加一次写入一次
     *
     * 1 统计使用时长
     * 2 比对时长上限，如果还剩24小时，提示一次
     * 3 远程增加时长：清除使用时长，并且这个码不可以重复使用
     *
     * 注意：
     * 程序卸载会自动清除内部存储，防止用户恶意手动删除外部存储
     * 程序进入后台停止计时
     */

    /**
     * 使用截止时间 2025年1月1日 如果使用截止时间>当前使用时间 可以使用， 如果截止时间<当前时间，判定为超出使用时间，禁止使用
     * 上次使用时间 2024年1月23日  如果上次使用时间<当前时间 更新上次时间  如果上次使用时间>当前时间 ，判定为修改时间了禁止使用
     * 当前使用时间 2024年1月24日
     */
    private fun isUseTimeOut(): Boolean {
        if (!appFile.exists()) {
            errorMsg = "文件缺失，请重新使用授权应用生成授权码"
            return true
        } else {
            val appTxtBean = readFileByLines(appFile)
            //软件使用时间上限
            val useMaxTime =
                if (appTxtBean.useTimeMax.isNullOrEmpty()) 0 else appTxtBean.useTimeMax.toLong()
            //软件上次使用时间
            val lastUseTime =
                if (appTxtBean.lastUseTime.isNullOrEmpty()) 0 else appTxtBean.lastUseTime.toLong()
            val currentTime = getTime().toLong()
            if (useMaxTime < currentTime) {
                errorMsg =
                    "使用时间超时\n" + "Android_id:${getAndroidId()}\n" + "请拍照本界面发送给杭州爱知工作人员添加时长"
                return true
            } else {
                if (lastUseTime < currentTime) {
                    /**
                     * 更新上次使用时间，可以正常使用
                     */
                    writeFileByLines(
                        appFile, RWUtil.AppTxtBean(
                            getAndroidId(), appTxtBean.useTimeMax, currentTime.toString()
                        )
                    )
                } else {
                    errorMsg =
                        "时间格式不一致\n上次使用时间${lastUseTime}\n请修改本机时间到大于上次使用时间"
                    return true
                }
            }
        }
        return false
    }


    /**
     * md5码由应用A生成将平板 {blankii+mac唯一标志} md5加密转变为不可识别码
     * 该算法也是将mac码生成md5码
     * 如果不存在，则提示缺少授权
     * 如果比对错误，提示比对错误，请重新授权
     * 如果存在则isValid 返回true
     *
     * 目的：
     * 1 保证只有先运行应用A才能运行应用B
     * 2 因为是离线状态，判断识别是不是授权平板只能生成识别码在本地，如果用户拷贝已授权平板的所有文件替换到新平板，这种方式也无法破解
     */
    private fun isValid() = checkValid()

    /**
     * 比对md5
     */
    private fun checkValid(): Boolean {
        val android_id = getAndroidId()
        /**
         * 文件路径是否存在
         */
        return if (!appFile.exists()) {
            errorMsg = "授权码文件不存在，请提前使用授权应用生成授权码"
            false
        } else {
            val appId = readFileByLines(appFile).appId

            /**
             * 解决bug 在我的手机Android15 四月一日正常， 四月九日发现本地的id 居然前边的部分变了，最后一节没变
             */
            val sAppId = appId.substring(appId.lastIndexOf("-"), appId.length)
            val sAndroid_id = android_id.substring(android_id.lastIndexOf("-"), android_id.length)
            if (sAppId == sAndroid_id) {
//                sAppId.toString().loge("blankii")
//                sAndroid_id.toString().loge("blankii")
                return true
            } else {
                errorMsg = "授权码匹对失败:\n错误id:${appId}\nAndroid_id:${android_id}"
                false
            }
        }
    }


    private fun initView() {
        binding.apply {

            //跳转到androidLibrary
            debugStatus.setOnClickListener {
                this@HomeActivity.startActivity<LibraryMainActivity>()
            }
            faultMsg.visibility = View.GONE
            faultMsg.movementMethod = ScrollingMovementMethod.getInstance()
//            binding.faultMsg.text = "出现故障信息\n$123213123132"
////            binding.faultMsg.text =
////                "出现故障\n故障码-地址4461:${hexArr[0]}\n故障码-地址4462:${hexArr[1]}"
//            binding.faultMsg.visibility = View.VISIBLE
            more.setOnClickListener {
                showAlertDialog()
            }
            saveBtn.setOnClickListener {
                /**
                 * 发送43705  0x5A5A
                 * 参数保存
                 */
                SocketManagerNew.sendWriteMsg(XML_ADDRESS_SAVE_PARAM, XML_VALUE_SAVE_PARAM)
                showSnackBar("发送成功")
            }
        }
        initNavigation()
        SocketManagerNew.initViewModel(mViewModel)
        binding.logMsg.movementMethod = ScrollingMovementMethod.getInstance()
        mViewModel.logData.observe(this) {
            if (isLog) {
                binding.logMsg.append(it)
            }
        }
    }

    private fun initNavigation() {
        findNavController(R.id.fragment_container_view).addOnDestinationChangedListener { controller, destination, arguments ->

            when (destination.id) {
                R.id.homeFragment -> {
                    /**
                     * 更新车型名称
                     */
                    binding.carModelView.text = currentCarName.substringBefore(".xml")
                    mViewModel.currentPage.value = FragmentPage.HOME_FRAG
                    isHomeFragment = true
                    binding.socketStatus.visibility = View.VISIBLE
                    binding.saveBtn.visibility = View.VISIBLE
                    if (binding.more.isVisible) {
                        return@addOnDestinationChangedListener
                    } else {
                        binding.more.visibility = View.VISIBLE
                    }
                }

                R.id.carChooseManagerFragment -> {
                    /**
                     * 更新车型名称
                     */
                    binding.carModelView.text = ""
                    mViewModel.currentPage.value = FragmentPage.ELSE
                    isHomeFragment = false
                    binding.more.visibility = View.GONE
                    binding.socketStatus.visibility = View.GONE
                    binding.saveBtn.visibility = View.GONE
                    /***
                     * 连续点击三下开启调试助手
                     */
                    ViewClickContinuousUtil.setViewConfig(
                        binding.logoView,
                        3,
                        callBack = object : ViewClickContinuousUtil.ClickContinuousCallback {
                            override fun success() {
                                //开启调试助手
                                mViewModel.debugTool = !mViewModel.debugTool
                                if (mViewModel.debugTool) {
                                    binding.debugStatus.visibility = View.VISIBLE
                                    binding.debugStatus.text =
                                        "调试助手已开启\r\n点击跳转到AndroidLibrary调试库界面"
                                } else {
                                    binding.debugStatus.visibility = View.GONE
                                    showSnackBar("调试助手:已关闭")
                                    val navHomeFragment =
                                        supportFragmentManager.findFragmentById(R.id.fragment_container_view) as NavHostFragment
                                    val carChooseManagerFragment =
                                        navHomeFragment.childFragmentManager.fragments[0]
                                    if (carChooseManagerFragment is CarChooseManagerFragment) {
                                        carChooseManagerFragment.hideXmlAddress()
                                    }
                                }
                            }

                            override fun currentCount(count: Int) {

                            }

                        })
                }

                else -> {
                    mViewModel.currentPage.value = FragmentPage.ELSE
                    isHomeFragment = false
                    binding.socketStatus.visibility = View.VISIBLE
                    binding.saveBtn.visibility = View.GONE
                    binding.more.visibility = View.GONE

                }
            }
        }
    }


    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (isHomeFragment && keyCode == KeyEvent.KEYCODE_BACK) {
            ViewClickContinuousUtil.backClickConfig(object :
                ViewClickContinuousUtil.BackClickCallback {
                override fun success() {
                    finish()
                }

                override fun clickOne() {
                    showSnackBar("再按一次返回键退出")
                }
            })
            return true
        }
        return super.onKeyDown(keyCode, event)
    }

    private var dialog: AlertDialog? = null

    /**
     * 显示输入对话框
     */
    private fun showAlertDialog() {
        if (dialog == null) {
            val dialogBinding = LayoutDialogMoreBinding.inflate(layoutInflater)
            val dialogBuilder = AlertDialog.Builder(this).setView(dialogBinding.root)
            dialog = dialogBuilder.show()
            val keyIsExist = DebugDataBean.xmlSettings.contains(XML_XS_BD)
            if (!keyIsExist) {
                "请检查该车型XML文件 XmlSetting中是否存在 是否显示标定界面".logw(TAG)
            } else if (!DebugDataBean.xmlSettings[XML_XS_BD]!!) {
                dialogBinding.biaoDingButton.visibility = View.GONE
            }
            dialogBinding.apply {
                /**
                 * 打开标定界面
                 */
                biaoDingButton.setOnClickListener {
                    dialog!!.hide()
                    val navController =
                        findNavController(this@HomeActivity, R.id.fragment_container_view)
                    if (currentCarName.contains(XML_DEVICE_NAME_GCH10)) {
                        navController.navigate(R.id.action_homeFragment_to_GCH10SensorSettingFragment)
                    } else {
                        navController.navigate(R.id.action_homeFragment_to_sensorSettingFragment2)
                    }
                }
                /**
                 * 保存文件
                 */
                saveFileButton.setOnClickListener {
                    dialog!!.hide()
                    val navController =
                        findNavController(this@HomeActivity, R.id.fragment_container_view)
                    navController.navigate(R.id.action_homeFragment_to_saveFileFragment)

                }
                /**
                 * 读取文件
                 */
                readFileButton.setOnClickListener {
                    dialog!!.hide()
                    val navController =
                        findNavController(this@HomeActivity, R.id.fragment_container_view)
                    navController.navigate(R.id.action_homeFragment_to_readFileFragment)
                }
                /**
                 * 显示版本号
                 */
                showVersionMsg.setOnClickListener {
                    dialog!!.hide()
                    val navController =
                        findNavController(this@HomeActivity, R.id.fragment_container_view)
                    navController.navigate(R.id.action_homeFragment_to_versionFragment)

                }
                /**
                 * 显示打印日志
                 */
                val navHomeFragment =
                    supportFragmentManager.findFragmentById(R.id.fragment_container_view) as NavHostFragment
                val homeFragment = navHomeFragment.childFragmentManager.fragments[0]
                if (homeFragment is HomeFragment) {
                    showLog.setOnCheckedChangeListener { buttonView, isChecked ->
                        dialog!!.hide()
                        if (isChecked) {
                            showLog()
                        } else {
                            closeLog()
                        }
                    }
                }
            }
        } else {
            dialog!!.show()
        }
    }

    fun showLog() {
        isLog = true
        binding.logMsg.visibility = View.VISIBLE
        binding.logMsg.text = "数据已清空\n"
    }

    private var isLog = false
    fun closeLog() {
        isLog = false
        binding.logMsg.visibility = View.GONE
    }

    override fun onSocketConnected(status: SocketConnectedStatus) {
        when (status) {
            SocketConnectedStatus.SUCCESS -> {
                binding.socketStatus.text = "与控制器连接成功"
            }

            SocketConnectedStatus.FAILED -> {
                binding.socketStatus.text = "与控制器连接失败"

            }

            SocketConnectedStatus.DISCONNECT -> {
                binding.socketStatus.text = "与控制器断开连接"
            }
        }
    }

    override fun onSocketMsg(msg: String) {
        showSnackBar(msg)
    }

    val stringBuilder = StringBuilder()
    override fun onSocketFaultMsg(hexArr: ArrayList<String>) {
        /**
         * 处理故障 todo 优化
         */
        var haveError = false//是否有故障
        for (i in hexArr.indices) {
            if (hexArr[i] != "0000") {
                val data = DebugDataBean.errorParent.itemList[i].bitArray
                val binaryString = CalcUtil.Hex2BinaryString(hexArr[i])//十六进制
                for (j in binaryString.indices) {
                    if (binaryString[j] == '1') {
                        stringBuilder.append("${data[j]}\n")
                    }
                }
                haveError = true
            }
        }
        if (haveError) {
            binding.faultMsg.text = "出现故障信息\n$stringBuilder"
//            binding.faultMsg.text =
//                "出现故障\n故障码-地址4461:${hexArr[0]}\n故障码-地址4462:${hexArr[1]}"
            binding.faultMsg.visibility = View.VISIBLE
            stringBuilder.clear()
        } else {
            binding.faultMsg.visibility = View.GONE
            binding.faultMsg.text = "无故障"
        }
    }


//        if ((hexArr[0] != "0000" || hexArr[1] != "0000")) {
//            stringBuilder.clear()
//            for (i in hexArr.indices) {
//                if (hexArr[i] != "0000") {
//                    val data = DebugDataBean.errorParent.itemList[i].bitArray
//                    val binaryString = CalcUtil.Hex2BinaryString(hexArr[i])//十六进制
//                    for (j in binaryString.indices) {
//                        if (binaryString[j] == '1') {
//                            stringBuilder.append("${data[j]}\n")
//                        }
//                    }
//                }
//
//            }
//            binding.faultMsg.text = "出现故障信息\n$stringBuilder"
////            binding.faultMsg.text =
////                "出现故障\n故障码-地址4461:${hexArr[0]}\n故障码-地址4462:${hexArr[1]}"
//            binding.faultMsg.visibility = View.VISIBLE
//        } else if ((hexArr[0] == "0000" && hexArr[1] == "0000")) {
//            binding.faultMsg.visibility = View.GONE
//            binding.faultMsg.text = "无故障"
//        }


    override fun onDestroy() {
        super.onDestroy()
        SocketManagerNew.unSubscribeSocketConnectionListener()
        /**
         * 热启动初始化
         */
        DebugDataBean.xmlMap.keys.forEach {
            DebugDataBean.xmlMap[it]!!.clear()
        }
    }
}